package com.treasure.web.controller;

import com.treasure.common.enums.*;
import com.treasure.common.exception.ServiceException;
import com.treasure.common.model.SessionUser;
import com.treasure.common.reponse.Response;
import com.treasure.common.types.EmailAddress;
import com.treasure.common.types.PhoneNumber;
import com.treasure.infrastructure.model.po.CorpInfo;
import com.treasure.infrastructure.model.po.CorpUserInfo;
import com.treasure.web.command.PasswordEditRequest;
import com.treasure.web.command.request.*;
import com.treasure.web.command.request.login.ExternalLoginRequest;
import com.treasure.web.command.request.login.LoginRequest;
import com.treasure.web.command.request.login.RegisterRequest;
import com.treasure.web.service.IAccountService;
import com.treasure.web.service.ICorpTrialApproveService;
import com.treasure.web.service.LoginHelper;
import com.treasure.web.service.SmsService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * 账户登录、注册 （用户端）
 *
 * @author sunhongmin
 * @date 2023/9/1 10:31
 * @description
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/treasure/auth")
public class LoginController extends LoginHelper {

    private final IAccountService accountService;
    private final SmsService smsService;
    private final ICorpTrialApproveService corpTrialApproveService;

    /**
     * 注册账户
     *
     * @param request 账户注册信息
     * @return 账户注册响应
     */
    @PostMapping("/register")
    public Response<String> register(@RequestBody RegisterRequest request) {
        accountService.register(request);
        return Response.success();
    }

    /**
     * 用户登录
     *
     * @param loginRequest 登录信息
     * @return
     * @description 验证码登录，将为新手机号创建新账户
     * 为了确认企业用户身份，非管理员登录必须携带企业认证码
     */
    @PostMapping("/login")
    public Response<String> login(@RequestBody @Validated({LoginRequest.NormalUserLoginValiadate.class}) LoginRequest loginRequest, HttpServletResponse servletResponse) {
        List<CorpUserInfo> corpUserInfoList = accountService.login(loginRequest, LoginRouteEnum.NORMAL_LOGIN_ROUTE);
        // 通过邀请码/企业码获取用户所属企业主体
        CorpInfo corpInfo = accountService.getCorpInfoFromInviteCode(loginRequest.getInvitationCode());
        if (Objects.isNull(corpInfo)) {
            throw new ServiceException("未能通过企业/高校认证码获取到主体信息，请重新尝试通过特定入口跳转登录");
        }

        CorpUserInfo corpUserInfo = corpUserInfoList.stream().filter(it -> Objects.equals(it.getCorpId(), corpInfo.getCorpId())).findFirst().orElse(new CorpUserInfo());
        String token = getToken(corpUserInfo);
        addCookie(servletResponse, token);
        SessionUser sessionUser = getSessionUserCache(corpUserInfo, IdentitiesEnum.NORMAL_USER);
        putCache(token, sessionUser);
        return Response.success("登录成功");
    }

    /**
     * 用户登出
     *
     * @return
     */
    @PostMapping("/logout")
    public Response<?> logout(HttpServletRequest servletRequest) {
        return tokenLogout(servletRequest);
    }


    /**
     * 发送短信验证码 （开发阶段固定yz123）
     *
     * @param verifyCodeSendRequest
     * @return
     */
    @PostMapping("/verify/code/send")
    public Response<?> verifyCodeSend(@RequestBody VerifyCodeSendRequest verifyCodeSendRequest) throws IOException {
        smsService.sendVerifyCode(new PhoneNumber(verifyCodeSendRequest.getPhoneNumber()), SmsUsageEnum.getByCode(verifyCodeSendRequest.getUsage()));
        return Response.success();
    }

    /**
     * 发送email验证码
     *
     * @param emailVerifyCodeSendRequest
     * @return
     */
    @PostMapping("/email/verify/code/send")
    public Response<?> verifyCodeSendWithEmail(@RequestBody EmailVerifyCodeSendRequest emailVerifyCodeSendRequest) throws IOException {
        smsService.sendEmailVerifyCode(emailVerifyCodeSendRequest.getInvitationCode(), new EmailAddress(emailVerifyCodeSendRequest.getEmailAddress()), SmsUsageEnum.getByCode(emailVerifyCodeSendRequest.getUsage()));
        return Response.success();
    }

    /**
     * 跳转登录
     *
     * @return
     */
    @PostMapping("/external/login")
    public Response<String> externalLogin(@RequestBody @Validated ExternalLoginRequest externalLoginRequest, HttpServletResponse servletResponse) {
        CorpUserInfo corpUserInfo = accountService.externalLogin(externalLoginRequest);
        String token = getToken(corpUserInfo);
        addCookie(servletResponse, token);
        SessionUser sessionUser = getSessionUserCache(corpUserInfo, IdentitiesEnum.NORMAL_USER);
        putCache(token, sessionUser);
        return Response.success("登录成功");
    }

//    /**
//     * 企业/高校账号开通试用
//     *
//     * @param createUnofficialCorpAccountRequest
//     * @return
//     */
//    @PostMapping("/corp/create")
//    public Response<?> createUnOfficialCorpAccount(@RequestBody @Validated({CreateCorpAccountRequest.CreateAccount.class}) CreateCorpAccountRequest createUnofficialCorpAccountRequest) throws IOException, IllegalAccessException {
//        accountService.createCorpAccount(createUnofficialCorpAccountRequest, RegisterChannelEnum.ACCESS_REGISTER);
//        return Response.success();
//    }

    /**
     * 企业试用提交申请
     * @param createCorpAccountRequest
     * @return
     */
    @PostMapping("/corp/trial/approve")
    public Response<String> corpTrialApprove(@Validated @RequestBody CreateCorpAccountRequest createCorpAccountRequest) {
        corpTrialApproveService.corpTrialApprove(createCorpAccountRequest);
        return Response.success();
    }


    /**
     * 修改密码 （原密码验证）
     *
     * @param editAccountPasswordRequest
     * @return
     */
    @PostMapping("/edit/password")
    public Response<String> editPasswordWord(@RequestBody @Validated EditAccountPasswordRequest editAccountPasswordRequest) {
        PasswordEditRequest passwordEditRequest = new PasswordEditRequest();
        passwordEditRequest.setPhoneNumber(editAccountPasswordRequest.getPhoneNumber());
        passwordEditRequest.setVerifyCode(editAccountPasswordRequest.getOriginPassword());
        passwordEditRequest.setNewPassWord(editAccountPasswordRequest.getNewPassWord());
        passwordEditRequest.setRePassword(editAccountPasswordRequest.getRePassword());
        passwordEditRequest.setLoginType(LoginTypeEnum.PASSWORD_WORD);
        accountService.editPassword(passwordEditRequest);
        return Response.success();
    }

    /**
     * 修改密码（验证码验证）
     *
     * @param editAccountPasswordByCodeRequest
     * @return
     */
    @PostMapping("/edit/password/code")
    public Response<String> editPasswordByCode(@RequestBody @Validated EditAccountPasswordByCodeRequest editAccountPasswordByCodeRequest) {
        PasswordEditRequest passwordEditRequest = new PasswordEditRequest();
        passwordEditRequest.setPhoneNumber(editAccountPasswordByCodeRequest.getPhoneNumber());
        passwordEditRequest.setVerifyCode(editAccountPasswordByCodeRequest.getVerifyCode());
        passwordEditRequest.setNewPassWord(editAccountPasswordByCodeRequest.getNewPassWord());
        passwordEditRequest.setRePassword(editAccountPasswordByCodeRequest.getRePassword());
        passwordEditRequest.setLoginType(LoginTypeEnum.VERIFY_CODE);
        accountService.editPassword(passwordEditRequest);
        return Response.success();
    }

}
